package com.mechat.common.user.service.Impl;

import com.mechat.common.common.annotation.RedissonLock;
import com.mechat.common.common.domain.enums.YesOrNoEnum;
import com.mechat.common.common.service.LockService;
import com.mechat.common.user.dao.UserBackpackDao;
import com.mechat.common.user.domain.entity.UserBackpack;
import com.mechat.common.user.domain.enums.IdempotentEnum;
import com.mechat.common.user.service.IUserBackpackService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.Objects;

@Service
public class IUserBackpackServiceImpl implements IUserBackpackService {
    @Autowired
    private LockService lockService;

    @Autowired
    private UserBackpackDao userBackpackDao;

    @Autowired
    @Lazy
    private IUserBackpackServiceImpl iUserBackpackService;

    @Override
    public void acquireItem(Long uid, Long itemId, IdempotentEnum idempotentEnum, String businessId) {
        String idempotent = getIdempotent(itemId, idempotentEnum, businessId);
        lockService.executeWithLock("acquireItem" + idempotent, () -> {
            // 判断幂等值是否存在
            UserBackpack userBackpack = userBackpackDao.getByIdempotent(idempotent);
            if (Objects.nonNull(userBackpack)) {
                return;
            }
            // 发放物品
            UserBackpack insert = UserBackpack.builder()
                    .uid(uid)
                    .itemId(itemId)
                    .status(YesOrNoEnum.NO.getStatus())
                    .idempotent(idempotent)
                    .build();
            userBackpackDao.save(insert);
        });
//        RLock lock = redissonClient.getLock("acquireItem" + idempotent);
//        AssertUtil.isTrue(lock.tryLock(), "请求太频繁，请稍后再试");
//        try {
//            // 判断幂等值是否存在
//            UserBackpack userBackpack = userBackpackDao.getByIdempotent(idempotent);
//            if (Objects.nonNull(userBackpack)) {
//                return;
//            }
//            // 发放物品
//            UserBackpack insert = UserBackpack.builder()
//                    .uid(uid)
//                    .itemId(itemId)
//                    .status(YesOrNoEnum.NO.getStatus())
//                    .idempotent(idempotent)
//                    .build();
//            userBackpackDao.save(insert);
//        } finally {
//            lock.unlock();
//        }
    }

    @Override
    public void acquireItemCustomLock(Long uid, Long itemId, IdempotentEnum idempotentEnum, String businessId) {
        String idempotent = getIdempotent(itemId, idempotentEnum, businessId);
        // 调用方式一，注解自己，自己调用
        iUserBackpackService.doAcquireItem(uid, itemId, idempotent);
        // 调用方式二
//        ((IUserBackpackServiceImpl) AopContext.currentProxy()).doAcquireItem(uid, itemId, idempotent);
    }

    // 使用自定义注解锁
    @RedissonLock(key = "#idempotent", waitTime = 5000)
    public void doAcquireItem(Long uid, Long itemId, String idempotent) {
        // 判断幂等值是否存在
        UserBackpack userBackpack = userBackpackDao.getByIdempotent(idempotent);
        if (Objects.nonNull(userBackpack)) {
            return;
        }
        // 发放物品
        UserBackpack insert = UserBackpack.builder()
                .uid(uid)
                .itemId(itemId)
                .status(YesOrNoEnum.NO.getStatus())
                .idempotent(idempotent)
                .build();
        userBackpackDao.save(insert);
    }

    private String getIdempotent(Long itemId, IdempotentEnum idempotentEnum, String businessId) {
        return String.format("%d_%d_%s", itemId, idempotentEnum.getType(), businessId);
    }
}
